import { Injectable } from '@nestjs/common';
import { Model } from 'mongoose';
import mongoose from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { OrderDto, QueryOrderPage } from '@/dto/order.dto';
import { Order, OrderDocument } from '@/schema/order.schema';

@Injectable()
export class OrderService {
  constructor(
    @InjectModel(Order.name) private orderModel: Model<OrderDocument>
  ) {}

  createOrder(id: string, order: OrderDto) {
    /**
     * model.create 方法在内部调用了 new Document() 来创建文档实例，并使用 save() 方法将其保存到数据库中。因此，它会自动处理文档的验证过程
     * 等同于：const orderDocument = new this.orderModel(order); orderDocument.save();
     */
    return this.orderModel.create({ creatorId: id, ...order });
  }

  findOrderById(id: string) {
    return this.orderModel
      .aggregate([
        {
          $match: { _id: new mongoose.Types.ObjectId(id) }
        },
        {
          $lookup: {
            from: 'users',
            localField: 'creatorId',
            foreignField: '_id',
            as: 'creator'
          }
        },
        {
          $sort: {
            createdAt: -1
          }
        },
        {
          $project: {
            creatorId: 0,
            __v: 0,
            creator: {
              __v: 0,
              password: 0
            }
          }
        }
      ])
      .exec();
  }

  async findOrdersByCreatorId(
    id: string,
    orderPage?: QueryOrderPage
  ): Promise<Api.Common.Page<OrderDocument>> {
    const { current = 1, size = 10, ...rest } = orderPage;
    const records = await this.orderModel
      .aggregate([
        {
          $match: {
            ...rest,
            creatorId: new mongoose.Types.ObjectId(id)
          }
        },
        {
          $sort: {
            createdAt: -1
          }
        },
        {
          $lookup: {
            from: 'users',
            localField: 'creatorId',
            foreignField: '_id',
            as: 'creator'
          }
        },
        {
          $skip: (current - 1) * size
        },
        {
          $limit: size
        },
        {
          $project: {
            creatorId: 0,
            __v: 0
          }
        }
      ])
      .exec();
    const total = await this.orderModel.countDocuments({
      ...rest,
      creatorId: id
    });
    return {
      records: records,
      total: total,
      current: orderPage.current,
      size: orderPage.size
    };
  }
}
